/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.dao.impl;

import cn.easyplatform.entities.BaseEntity;
import cn.easyplatform.entities.EntityInfo;
import cn.easyplatform.entities.beans.LogicBean;
import cn.easyplatform.entities.beans.ResourceBean;
import cn.easyplatform.entities.beans.page.PageBean;
import cn.easyplatform.entities.beans.report.JasperReportBean;
import cn.easyplatform.entities.beans.report.JxlsReport;
import cn.easyplatform.entities.transform.TransformerFactory;
import cn.easyplatform.lang.Lang;
import cn.easyplatform.lang.Nums;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.lang.stream.StringOutputStream;
import cn.easyplatform.studio.dao.*;
import cn.easyplatform.studio.dao.transaction.JdbcTransactions;
import cn.easyplatform.studio.utils.StringUtil;
import cn.easyplatform.studio.vos.EntityVo;
import cn.easyplatform.studio.vos.MessageVo;
import cn.easyplatform.type.EntityType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.stream.IntStream;

/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
public abstract class AbstractEntityDao implements EntityDao {

    protected final static Logger log = LoggerFactory.getLogger(AbstractEntityDao.class);

    protected DataSource ds;

    /**
     * @param ds
     */
    public AbstractEntityDao(DataSource ds) {
        this.ds = ds;
    }

    protected abstract Dialect getDialect();

    @Override
    public List<EntityVo> selectList(String statement, Page page,
                                     String... parameters) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            StringBuilder sb = new StringBuilder();
            if (page != null && page.isGetTotal()) {
                sb.append("select count(1) from (").append(statement)
                        .append(") c");
                pstmt = conn.prepareStatement(sb.toString());
                if (parameters.length > 0) {
                    for (int i = 0; i < parameters.length; i++)
                        pstmt.setString(i + 1, parameters[i]);
                }
                rs = pstmt.executeQuery();
                rs.next();
                page.setTotalCount(Nums.toInt(rs.getObject(1).toString(), 0));
                DaoUtils.closeQuietly(pstmt, rs);
                sb.setLength(0);
            }
            sb.append(statement);
            if (page != null) {
                if (page.isGetTotal() && page.getTotalCount() == 0)
                    return Collections.emptyList();
                if (page.getOrderBy() != null)
                    sb.append(" order by ").append(page.getOrderBy());
                statement = getDialect().getPageSql(sb.toString(), page);
            }
            log.debug("getList->%s", statement);
            pstmt = conn.prepareStatement(statement);
            if (parameters.length > 0) {
                for (int i = 0; i < parameters.length; i++)
                    pstmt.setString(i + 1, parameters[i]);
            }
            rs = pstmt.executeQuery();
            List<EntityVo> loadedObjects = new ArrayList<EntityVo>();
            while (rs.next()) {
                EntityVo vo = new EntityVo(rs.getString(1), rs.getString(2),
                        rs.getString(3), rs.getString(4), rs.getString(5));
                loadedObjects.add(vo);
            }
            return loadedObjects;
        } catch (SQLException ex) {
            log.error("selectList", ex);
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T extends BaseEntity> List<T> selectEntity(String query, Page page,
                                                       String... parameters) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            StringBuilder sb = new StringBuilder();
            if (page != null && page.isGetTotal()) {
                sb.append("select count(1) from (").append(query).append(") c");
                pstmt = conn.prepareStatement(sb.toString());
                if (parameters.length > 0) {
                    for (int i = 0; i < parameters.length; i++)
                        pstmt.setString(i + 1, parameters[i]);
                }
                rs = pstmt.executeQuery();
                rs.next();
                page.setTotalCount(Nums.toInt(rs.getObject(1).toString(), 0));
                DaoUtils.closeQuietly(pstmt, rs);
                sb.setLength(0);
            }
            sb.append(query);
            if (page != null) {
                if (page.isGetTotal() && page.getTotalCount() == 0)
                    return Collections.emptyList();
                if (page.getOrderBy() != null)
                    sb.append(" order by ").append(page.getOrderBy());
                query = getDialect().getPageSql(sb.toString(), page);
            }
            log.debug("selectEntity->%s", query);
            pstmt = conn.prepareStatement(query);
            if (parameters.length > 0) {
                for (int i = 0; i < parameters.length; i++)
                    pstmt.setString(i + 1, parameters[i]);
            }
            rs = pstmt.executeQuery();
            int size = rs.getMetaData().getColumnCount();
            List<T> loadedObjects = new ArrayList<T>();
            while (rs.next()) {
                EntityInfo e = new EntityInfo();
                e.setId(rs.getString(1));
                e.setName(rs.getString(2));
                e.setDescription(rs.getString(3));
                if (size > 3)
                    e.setType(rs.getString(4));
                if (size > 4)
                    e.setSubType(rs.getString(5));
                if (size > 5) {
                    e.setContent(rs.getString(6));
                    T baseT = TransformerFactory.newInstance().transformFromXml(e);
                    //第7个默认为ext0,第8个默认为ext1
                    if (size == 8) {
                        if (baseT instanceof PageBean) {
                            ((PageBean) baseT).setAjax(rs.getString(7));
                            ((PageBean) baseT).setMil(rs.getString(8));
                        }
                    }
                    loadedObjects.add(baseT);
                } else
                    loadedObjects.add((T) e);
            }
            return loadedObjects;
        } catch (SQLException ex) {
            log.error("selectEntity", ex);
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public List<EntityVo> selectModel(String statement, String... parameters) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            log.debug("selectModel->%s", statement);
            pstmt = conn.prepareStatement(statement);
            if (parameters.length > 0) {
                for (int i = 0; i < parameters.length; i++)
                    pstmt.setString(i + 1, parameters[i]);
            }
            rs = pstmt.executeQuery();
            List<EntityVo> loadedObjects = new ArrayList<EntityVo>();
            while (rs.next()) {
                EntityVo vo = new EntityVo(rs.getString(1), rs.getString(2),
                        rs.getString(3));
                loadedObjects.add(vo);
            }
            return loadedObjects;
        } catch (SQLException ex) {
            log.error("selectModel", ex);
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public ResourceBean getDatasource(String id) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            pstmt = conn
                    .prepareStatement("select name,desp,content from ep_model_info where modelId=?");
            pstmt.setString(1, id);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                EntityInfo e = new EntityInfo();
                e.setId(id);
                e.setName(rs.getString(1));
                e.setDescription(rs.getString(2));
                e.setType(EntityType.DATASOURCE.getName());
                e.setContent(rs.getString(3));
                return TransformerFactory.newInstance().transformFromXml(e);
            }
            return null;
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    /**
     * 禁止用来查询参数和作为参数更新保存的操作
     * @param query
     * @param parameters
     * @return
     */
    @Override
    public Object selectObject(String query, Object... parameters) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            pstmt = conn
                    .prepareStatement(query);
            if (parameters.length > 0) {
                for (int i = 0; i < parameters.length; i++)
                    pstmt.setObject(i + 1, parameters[i]);
            }
            rs = pstmt.executeQuery();
            if (rs.next()) {
                ResultSetMetaData rsmd = rs.getMetaData();
                return DaoUtils.getValue(rs, rsmd, 1);
            }
            return null;
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public List<MessageVo> selectMessage(String statement, String... parameters) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            log.debug("selectModel->%s", statement);
            pstmt = conn.prepareStatement(statement);
//            if (parameters.length > 0) {
//                for (int i = 0; i < parameters.length; i++)
//                    pstmt.setString(i + 1, parameters[i]);
//            }
            rs = pstmt.executeQuery();
            List<MessageVo> loadedObjects = new ArrayList<MessageVo>();
            while (rs.next()) {
                MessageVo vo = new MessageVo();
                vo.setCode(rs.getString(1));
                vo.setZh_cn(rs.getString(2));
                vo.setZh_tw(rs.getString(3));
                vo.setEn_us(rs.getString(4));
                vo.setJa_jp(rs.getString(5));
                vo.setKo_kr(rs.getString(6));
                vo.setDe_de(rs.getString(7));
                vo.setFr_fr(rs.getString(8));
                vo.setIt_it(rs.getString(9));
                vo.setStatus(rs.getString(10));
                vo.setMSG_TYPE(rs.getString(11));
                loadedObjects.add(vo);
            }
            return loadedObjects;
        } catch (SQLException ex) {
            log.error("selectModel", ex);
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public HashMap<String, Object> selectCommonOne(String query, Object... parameters) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            pstmt = conn
                    .prepareStatement(query);
            if (parameters != null && parameters.length > 0) {
                for (int i = 0; i < parameters.length; i++)
                    pstmt.setObject(i + 1, parameters[i]);
            }
            rs = pstmt.executeQuery();
            if (rs.next()) {
                HashMap<String, Object> res = new HashMap<>();
                ResultSetMetaData rsmd = rs.getMetaData();
                final ResultSet rsTmp = rs;
                IntStream.rangeClosed(1, rsmd.getColumnCount()).forEach(i -> {
                    String name = null;
                    try {
                        if (rsmd.getColumnLabel(i) != null) {
                            name = rsmd.getColumnLabel(i);
                        }
                        else {
                            name = rsmd.getColumnName(i);
                        }
                        res.put(name, rsTmp.getObject(i));
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                });
                return res;
            }
            return null;
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public List<ResourceBean> getDatasources(String projectId) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            pstmt = conn
                    .prepareStatement("select modelId,name,desp,content from ep_model_info where createUser=?");
            pstmt.setString(1, projectId);
            rs = pstmt.executeQuery();
            List<ResourceBean> rbs = new ArrayList<ResourceBean>();
            while (rs.next()) {
                EntityInfo e = new EntityInfo();
                e.setId(rs.getString(1));
                e.setName(rs.getString(2));
                e.setDescription(rs.getString(3));
                e.setType(EntityType.DATASOURCE.getName());
                e.setContent(rs.getString(4));
                ResourceBean rb = TransformerFactory.newInstance()
                        .transformFromXml(e);
                rbs.add(rb);
            }
            return rbs;
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public boolean exists(String table) {
        Statement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            pstmt = conn.createStatement();
            rs = pstmt.executeQuery("select count(*) from " + table
                    + " where 1<>1");
            if (rs.next())
                return true;
            return false;
        } catch (SQLException ex) {
            return false;
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public boolean exists(String table, String id) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            pstmt = conn.prepareStatement("select type from " + table
                    + " where entityId=?");
            pstmt.setString(1, id);
            rs = pstmt.executeQuery();
            return rs.next();
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T extends BaseEntity> T getEntity(String table, String id) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            pstmt = conn
                    .prepareStatement("select name,desp,type,subType,content,ext0,ext1 from "
                            + table + " where entityId=?");
            pstmt.setString(1, id);
            rs = pstmt.executeQuery();
            //数据库查询后判断类型,选择不同的实体类
            if (rs.next()) {
                String type = rs.getString(3);
                if (type.equals(EntityType.LOGIC.getName())) {
                    LogicBean logic = new LogicBean();
                    logic.setId(id);
                    logic.setName(rs.getString(1));
                    logic.setDescription(rs.getString(2));
                    logic.setType(rs.getString(3));
                    logic.setSubType(rs.getString(4));
                    logic.setContent(rs.getString(5));
                    return (T) logic;
                } else if (type.equals(EntityType.REPORT.getName())) {
                    String subType = rs.getString(4);
                    if (subType.equals("Jasper")) {
                        JasperReportBean report = TransformerFactory.newInstance()
                                .transformFromXml(JasperReportBean.class,
                                        Lang.ins(rs.getString(5)));
                        report.setId(id);
                        report.setName(rs.getString(1));
                        report.setDescription(rs.getString(2));
                        report.setType(rs.getString(3));
                        report.setSubType(rs.getString(4));
                        return (T) report;
                    } else {
                        JxlsReport report = TransformerFactory.newInstance().transformFromXml(JxlsReport.class, Lang.ins(rs.getString(5)));
                        report.setId(id);
                        report.setName(rs.getString(1));
                        report.setDescription(rs.getString(2));
                        report.setType(rs.getString(3));
                        report.setSubType(rs.getString(4));
                        return (T) report;
                    }
                } else if (type.equals(EntityType.PAGE.getName())) {
                    PageBean e = TransformerFactory.newInstance().transformFromXml(PageBean.class, Lang.ins(rs.getString(5)));
                    e.setId(id);
                    e.setName(rs.getString(1));
                    e.setDescription(rs.getString(2));
                    e.setType(rs.getString(3));
                    e.setSubType(rs.getString(4));
                    if (Strings.isBlank(rs.getString(6)) == false)
                        e.setAjax(rs.getString(6));
                    if (Strings.isBlank(rs.getString(7)) == false)
                        e.setMil(rs.getString(7));
                    return (T) e;
                } else {
                    EntityInfo e = new EntityInfo();
                    e.setId(id);
                    e.setName(rs.getString(1));
                    e.setDescription(rs.getString(2));
                    e.setType(rs.getString(3));
                    e.setSubType(rs.getString(4));
                    e.setContent(rs.getString(5));
                    return TransformerFactory.newInstance().transformFromXml(e);
                }
            }
            return null;
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public <T extends BaseEntity> List<T> getEntityList(String table, List<String> idList) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            StringBuffer buffer = new StringBuffer("select entityId,name,desp,type,subType,content,ext0,ext1 from "
                    + table + " where entityId in(");
            for (String idString : idList) {
                buffer.append("'");
                buffer.append(idString);
                buffer.append("',");
            }
            buffer.deleteCharAt(buffer.length() - 1);
            buffer.append(")");
            pstmt = conn
                    .prepareStatement(buffer.toString());
            rs = pstmt.executeQuery();
            List<T> list = new ArrayList<>();
            while (rs.next()) {
                String type = rs.getString(4);
                if (type.equals(EntityType.LOGIC.getName())) {
                    LogicBean logic = new LogicBean();
                    logic.setId(rs.getString(1));
                    logic.setName(rs.getString(2));
                    logic.setDescription(rs.getString(3));
                    logic.setType(rs.getString(4));
                    logic.setSubType(rs.getString(5));
                    logic.setContent(rs.getString(6));
                    list.add((T) logic);
                } else if (type.equals(EntityType.REPORT.getName())) {
                    String subType = rs.getString(5);
                    if (subType.equals("Jasper")) {
                        JasperReportBean report = TransformerFactory.newInstance()
                                .transformFromXml(JasperReportBean.class,
                                        Lang.ins(rs.getString(6)));
                        report.setId(rs.getString(1));
                        report.setName(rs.getString(2));
                        report.setDescription(rs.getString(3));
                        report.setType(rs.getString(4));
                        report.setSubType(rs.getString(5));
                        list.add((T) report);
                    } else {
                        JxlsReport report = TransformerFactory.newInstance().transformFromXml(JxlsReport.class, Lang.ins(rs.getString(6)));
                        report.setId(rs.getString(1));
                        report.setName(rs.getString(2));
                        report.setDescription(rs.getString(3));
                        report.setType(rs.getString(4));
                        report.setSubType(rs.getString(5));
                        list.add((T) report);
                    }
                } else if (type.equals(EntityType.PAGE.getName())) {
                    PageBean e = TransformerFactory.newInstance().transformFromXml(PageBean.class, Lang.ins(rs.getString(6)));
                    e.setId(rs.getString(1));
                    e.setName(rs.getString(2));
                    e.setDescription(rs.getString(3));
                    e.setType(rs.getString(4));
                    e.setSubType(rs.getString(5));
                    if (Strings.isBlank(rs.getString(7)) == false)
                        e.setAjax(rs.getString(7));
                    if (Strings.isBlank(rs.getString(8)) == false)
                        e.setMil(rs.getString(8));
                    list.add((T) e);
                } else {
                    EntityInfo e = new EntityInfo();
                    e.setId(rs.getString(1));
                    e.setName(rs.getString(2));
                    e.setDescription(rs.getString(3));
                    e.setType(rs.getString(4));
                    e.setSubType(rs.getString(5));
                    e.setContent(rs.getString(6));
                    list.add((T) TransformerFactory.newInstance().transformFromXml(e));
                }
            }
            return list;
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public List<EntityVo> selectListWithID(String table, List<String> idList) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            StringBuffer entityStr = new StringBuffer("'");
            entityStr.append(StringUtil.listToString(idList, "','")).append("'");
            pstmt = conn.prepareStatement("select entityId,name,desp,type,subType from "
                    + table + " where entityId IN (" + entityStr + ")");
            rs = pstmt.executeQuery();
            List<EntityVo> loadedObjects = new ArrayList<EntityVo>();
            while (rs.next()) {
                EntityVo vo = new EntityVo(rs.getString(1), rs.getString(2),
                        rs.getString(3), rs.getString(4), rs.getString(5));
                loadedObjects.add(vo);
            }
            return loadedObjects;
        } catch (SQLException ex) {
            log.error("selectModel", ex);
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    /**
     * 没有组装数据，需要手动组装数据
     * @param table
     * @param id
     * @return
     */
    @Override
    public EntityInfo getEntry(String table, String id) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            pstmt = conn
                    .prepareStatement("select name,desp,type,subType,content,ext0,ext1 from "
                            + table + " where entityId=?");
            pstmt.setString(1, id);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                EntityInfo entity = new EntityInfo();
                entity.setId(id);
                entity.setName(rs.getString(1));
                entity.setDescription(rs.getString(2));
                entity.setType(rs.getString(3));
                entity.setSubType(rs.getString(4));
                entity.setContent(rs.getString(5));
                entity.setExt0(rs.getString(6));
                entity.setExt1(rs.getString(7));
                return entity;
            }
            return null;
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public void save(String projectId, String table, EntityInfo entity) {
        if (entity.getStatus() != 'C' && entity.getStatus() != 'U'
                && entity.getStatus() != 'D')
            return;
        log.debug("save [%s]:%s-%s", entity.getStatus(), entity.getId(),
                entity.getName());
        PreparedStatement pstmt = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            if (entity.getStatus() == 'C') {
                pstmt = conn
                        .prepareStatement("insert into "
                                + table
                                + " (entityId,name,desp,type,subType,content,createDate,createUser,status,ext0, ext1) values(?,?,?,?,?,?,?,?,?,?,?)");
                pstmt.setString(1, entity.getId());
                pstmt.setString(2, entity.getName());
                pstmt.setString(3, entity.getDescription());
                pstmt.setString(4, entity.getType());
                pstmt.setString(5, entity.getSubType());
                pstmt.setString(6, entity.getContent());
                pstmt.setTimestamp(7, new Timestamp(System.currentTimeMillis()));
                pstmt.setString(8, entity.getUpdateUser());
                pstmt.setString(9, "C");
                pstmt.setString(10, entity.getExt0());
                pstmt.setString(11, entity.getExt1());
                pstmt.executeUpdate();
            } else if (entity.getStatus() == 'U') {
                pstmt = conn
                        .prepareStatement("update "
                                + table
                                + " set name=?,desp=?,subType=?,content=?,updateDate=?,updateUser=?,status='U',ext0=?,ext1=? where entityId=?");
                pstmt.setString(1, entity.getName());
                pstmt.setString(2, entity.getDescription());
                pstmt.setString(3, entity.getSubType());
                pstmt.setString(4, entity.getContent());
                pstmt.setTimestamp(5, new Timestamp(System.currentTimeMillis()));
                pstmt.setString(6, entity.getUpdateUser());
                pstmt.setString(7, entity.getExt0());
                pstmt.setString(8, entity.getExt1());
                pstmt.setString(9, entity.getId());
                pstmt.executeUpdate();
            } else {
                if (entity.getContent() == null) {
                    pstmt = conn.prepareStatement("SELECT name,desp,type,subType,content,ext0,ext1 from "
                            + table + " where entityId=?");
                    pstmt.setString(1, entity.getId());
                    ResultSet rs = pstmt.executeQuery();
                    if (rs.next()) {
                        entity.setName(rs.getString("name"));
                        entity.setType(rs.getString("type"));
                        entity.setSubType(rs.getString("subType"));
                        entity.setContent(rs.getString("content"));
                        entity.setExt0(rs.getString("ext0"));
                        entity.setExt1(rs.getString("ext1"));
                    }
                    rs.close();
                    pstmt.close();
                    rs = null;
                    pstmt = null;
                }
                pstmt = conn.prepareStatement("delete from " + table
                        + " where entityId=?");
                pstmt.setString(1, entity.getId());
                pstmt.executeUpdate();
            }
            pstmt.close();
            pstmt = null;

            pstmt = conn
                    .prepareStatement("SELECT keyvalue FROM ep_serial_info WHERE keyname=?");
            pstmt.setString(1, projectId);
            ResultSet rs = pstmt.executeQuery();
            long versionNo = 0;
            if (rs.next())
                versionNo = rs.getLong(1);
            rs.close();
            pstmt.close();
            rs = null;
            pstmt = null;
            if (0 == versionNo)
                throw new SQLException("'" + projectId
                        + "' not found in table 'ep_serial_info'");
            if ("Page".equals(entity.getType())) {
                if (Strings.isBlank(entity.getContent()) == false) {
                    PageBean e = TransformerFactory.newInstance().transformFromXml(PageBean.class, Lang.ins(entity.getContent()));
                    e.setMil(entity.getExt1());
                    e.setAjax(entity.getExt0());
                    StringBuilder sb = new StringBuilder();
                    StringOutputStream os = new StringOutputStream(sb);
                    TransformerFactory.newInstance().transformToXml(e, os);
                    entity.setContent(sb.toString());
                }
            }

            pstmt = conn
                    .prepareStatement("INSERT INTO "
                            + table
                            + "_repo(versionNo,entityId,name,desp,type,subType,content,updateDate,updateUser,status) VALUES(?,?,?,?,?,?,?,?,?,?)");
            pstmt.setLong(1, versionNo);
            pstmt.setString(2, entity.getId());
            pstmt.setString(3, entity.getName());
            pstmt.setString(4, entity.getDescription());
            pstmt.setString(5, entity.getType());
            pstmt.setString(6, entity.getSubType());
            pstmt.setString(7, entity.getContent());
            pstmt.setTimestamp(8, new Timestamp(System.currentTimeMillis()));
            pstmt.setString(9, entity.getUpdateUser());
            pstmt.setString(10, entity.getStatus() + "");
            pstmt.execute();
            pstmt.close();
            pstmt = null;

            pstmt = conn
                    .prepareStatement("UPDATE ep_serial_info SET keyvalue=keyvalue+1 WHERE keyname=?");
            pstmt.setString(1, projectId);
            pstmt.execute();

        } catch (SQLException ex) {
            log.error(ex.getMessage(), ex);
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt);
        }
    }

    @Override
    public List<String> getColumnNameList(String table) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            //AND Table_schema='cj_data'
            pstmt = conn
                    .prepareStatement("select COLUMN_NAME from information_schema.COLUMNS where table_name = ? and Table_schema = ?");
            pstmt.setString(1, table);
            pstmt.setString(2, conn.getCatalog());
            List<String> columnNameList = new ArrayList<>();
            rs = pstmt.executeQuery();
            while (rs.next()) {
                columnNameList.add(rs.getString(1));
            }
            return columnNameList;
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }
}
